Impacto del Estilo de Vida en la Salud.🫀¶
Introducción y Planteamiento del Problema.¶
El estilo de vida y los hábitos diarios juegan un papel fundamental en la salud general de los individuos y en la prevalencia de diversas condiciones. La creciente disponibilidad de datos sobre salud y estilo de vida ofrece una oportunidad única para desentrañar las complejas interconexiones entre nuestras decisiones cotidianas y nuestro bienestar físico y mental.🙇🏼♂️
Este proyecto tiene como objetivo principal identificar y analizar las correlaciones y patrones clave entre diversas variables de comportamiento, demográficas y de salud, utilizando el "Kaggle Health and Lifestyle Dataset". A través de un Análisis Exploratorio de Datos (EDA) exhaustivo, buscamos comprender cómo los factores del estilo de vida se asocian con indicadores de salud específicos.📊
Para lograr este objetivo, buscaremos responder las siguientes preguntas clave❓:
- Correlaciones de Factores de Estilo de Vida con Indicadores de Salud: ¿Existe una relación significativa entre hábitos como la frecuencia de ejercicio, la calidad de la dieta, el consumo de alcohol y el tabaquismo, y la presencia de enfermedades crónicas, el Índice de Masa Corporal (IMC) o el nivel de estrés?🍟
- Influencia de Variables Demográficas: ¿Cómo interactúan la edad y el género con los hábitos de estilo de vida y los resultados de salud observados en el dataset?🌎
- Impacto del Sueño y Estrés: ¿De qué manera las horas de sueño y el nivel de estrés se correlacionan con la salud física, evidenciada por el Índice de Masa Corporal (IMC) y la presencia de enfermedades crónicas?💤
Los hallazgos de este análisis podrían proporcionar información valiosa para:
- Identificar factores de riesgo y protectores relacionados con el estilo de vida.
- Informar campañas de salud pública y recomendaciones personalizadas para un mayor bienestar.
- Guiar futuras investigaciones sobre la causalidad y los mecanismos subyacentes de las relaciones entre estilo de vida y salud.
Iniciaremos importando las librerías que utilizaremos en este proyecto.📚¶
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import seaborn as sns
A continuación, exportaremos el conjunto de datos para realizar un análisis exploratorio y obtener métricas relevantes.📐¶
df = pd.read_csv('../data/healt.csv')
print('Vista de las primeras filas del DataSet: \n')
df.head()
Vista de las primeras filas del DataSet:
| ID | Age | Gender | Height_cm | Weight_kg | BMI | Smoker | Exercise_Freq | Diet_Quality | Alcohol_Consumption | Chronic_Disease | Stress_Level | Sleep_Hours | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 56 | Other | 177.6 | 37.3 | 11.8 | Yes | NaN | Poor | NaN | No | 9 | 8.5 |
| 1 | 2 | 69 | Other | 169.3 | 70.7 | 24.7 | No | 1-2 times/week | Good | High | No | 2 | 5.9 |
| 2 | 3 | 46 | Female | 159.1 | 69.0 | 27.3 | No | Daily | Excellent | Moderate | No | 3 | 4.8 |
| 3 | 4 | 32 | Male | 170.6 | 76.4 | 26.3 | No | 3-5 times/week | Excellent | Moderate | No | 9 | 6.6 |
| 4 | 5 | 60 | Male | 158.4 | 60.4 | 24.1 | No | 3-5 times/week | Excellent | Low | Yes | 6 | 6.1 |
print('Información general del DataSet: \n')
df.info()
Información general del DataSet: <class 'pandas.core.frame.DataFrame'> RangeIndex: 7500 entries, 0 to 7499 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID 7500 non-null int64 1 Age 7500 non-null int64 2 Gender 7500 non-null object 3 Height_cm 7500 non-null float64 4 Weight_kg 7500 non-null float64 5 BMI 7500 non-null float64 6 Smoker 7500 non-null object 7 Exercise_Freq 5621 non-null object 8 Diet_Quality 7500 non-null object 9 Alcohol_Consumption 5608 non-null object 10 Chronic_Disease 7500 non-null object 11 Stress_Level 7500 non-null int64 12 Sleep_Hours 7500 non-null float64 dtypes: float64(4), int64(3), object(6) memory usage: 761.8+ KB
print('Estadísticas descriptivas del DataSet: \n')
df.describe()
Estadísticas descriptivas del DataSet:
| ID | Age | Height_cm | Weight_kg | BMI | Stress_Level | Sleep_Hours | |
|---|---|---|---|---|---|---|---|
| count | 7500.000000 | 7500.000000 | 7500.000000 | 7500.000000 | 7500.000000 | 7500.000000 | 7500.000000 |
| mean | 3750.500000 | 43.653333 | 164.949467 | 70.036040 | 26.032493 | 5.591867 | 7.002933 |
| std | 2165.207842 | 14.911816 | 9.960921 | 14.741595 | 6.432411 | 2.865983 | 1.514014 |
| min | 1.000000 | 18.000000 | 124.500000 | 17.700000 | 6.500000 | 1.000000 | 1.900000 |
| 25% | 1875.750000 | 31.000000 | 158.100000 | 59.900000 | 21.600000 | 3.000000 | 6.000000 |
| 50% | 3750.500000 | 43.000000 | 164.900000 | 70.100000 | 25.600000 | 6.000000 | 7.000000 |
| 75% | 5625.250000 | 57.000000 | 171.600000 | 80.100000 | 30.100000 | 8.000000 | 8.000000 |
| max | 7500.000000 | 69.000000 | 197.000000 | 128.500000 | 56.800000 | 10.000000 | 12.600000 |
NOTA: En esta sección, podemos observar datos clave como promedios, conteos, máximos y mínimos.
- La edad promedio de los participantes es de 43.65 años.
- La estatura promedio es de 164.64 cm.
- En cuanto a las edades, el valor máximo es 69 años y el mínimo es 18.
- Asimismo, se ofrecen detalles adicionales sobre la distribución de los datos.
print('Conteos nulos por columnas en el DataSet: \n')
df.isnull().sum()
Conteos nulos por columnas en el DataSet:
ID 0 Age 0 Gender 0 Height_cm 0 Weight_kg 0 BMI 0 Smoker 0 Exercise_Freq 1879 Diet_Quality 0 Alcohol_Consumption 1892 Chronic_Disease 0 Stress_Level 0 Sleep_Hours 0 dtype: int64
A continuación, analizamos la correlación entre las variables numéricas con el fin de determinar cuáles presentan una influencia significativa para el análisis de datos.📈¶
num_cols = ['Age', 'Height_cm', 'Weight_kg', 'BMI', 'Sleep_Hours', 'Stress_Level']
df_map = df[num_cols].copy()
correlation = df_map.corr()
grap = px.imshow(
correlation,
text_auto=True,
aspect="auto",
color_continuous_scale=px.colors.sequential.RdBu,
color_continuous_midpoint=0,
title="Mapa de Calor de Correlación entre Variables Numéricas."
)
grap.update_layout(
xaxis_title="Variables Numéricas.",
yaxis_title="Variables Numéricas.",
title_font_size=20,
height=700,
width=1000,
font=dict(
family="Arial, sans-serif",
size=14,
color="Black"
)
)
grap.update_xaxes(tickfont=dict(size=10))
grap.update_yaxes(tickfont=dict(size=10))
grap.show()
El mapa de calor permite interpretar la relación entre variables numéricas de la siguiente manera.🔥¶
- Una correlación positiva fuerte se evidencia con valores próximos a 1.
- Una correlación débil o inexistente se asocia con valores cercanos a 0.
- Una correlación negativa fuerte se observa en valores próximos a -1.
Ejemplo:
- Se observa una fuerte correlación positiva entre la variable peso y el IMC. Esta relación es intuitiva, dado que un mayor peso corporal se asocia directamente con un aumento en el índice de masa corporal.🏋🏼
Relación entre estas variables con su gráfica:¶
ps = px.scatter(
df,
x="Weight_kg",
y="BMI",
title = "Relación entre Peso Corporal e Índice de Masa Corporal.",
labels={"Weight_kg": "Peso Corporal (kg)", "BMI": "Índice de Masa Corporal"},
hover_data=['Age', 'Gender', 'Height_cm'],
trendline="ols",
color_discrete_sequence=['#0000CD']
)
ps.update_traces(marker=dict(size=8, opacity=0.7, line=dict(width=0.5, color='DarkSlateGrey')),
selector=dict(mode='markers'))
ps.update_layout(
xaxis_title="Peso Corporal (kg)",
yaxis_title="Índice de Masa Corporal (BMI)",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
)
)
ps.show()
ps_n = px.scatter(
df,
x="Height_cm",
y="BMI",
title = "Relación entre Altura e Índice de Masa Corporal.",
labels={"Height_cm": "Altura (cm)", "BMI": "Índice de Masa Corporal"},
hover_data=['Age', 'Gender', 'Weight_kg'],
trendline="ols",
color_discrete_sequence=['#DC3912']
)
ps_n.update_traces(marker=dict(size=8, opacity=0.7, line=dict(width=0.5, color='DarkSlateGrey')),
selector=dict(mode='markers'))
ps_n.update_layout(
xaxis_title="Altura (cm)",
yaxis_title="Índice de Masa Corporal (BMI)",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
)
)
ps_n.show()
Limpieza y Preprocesamiento de Datos. 🧼¶
Este es uno de los pasos más críticos en cualquier proyecto de análisis de datos. Los datos rara vez vienen en un formato perfecto para el análisis. Basándonos en la inspección anterior, necesitamos transformar y limpiar el dataset para asegurarnos de que sea preciso, consistente y esté en el formato correcto para responder a nuestras preguntas de investigación.
Para ello creamos copias de nuestro Dataframe, esto para tener ambas fuentes, la inicial y la que se limpio.
df_clean = df.copy()
Mostramos las 5 primeras filas para ver si hay algun dato nulo presente.
df_clean.head(5)
| ID | Age | Gender | Height_cm | Weight_kg | BMI | Smoker | Exercise_Freq | Diet_Quality | Alcohol_Consumption | Chronic_Disease | Stress_Level | Sleep_Hours | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 56 | Other | 177.6 | 37.3 | 11.8 | Yes | NaN | Poor | NaN | No | 9 | 8.5 |
| 1 | 2 | 69 | Other | 169.3 | 70.7 | 24.7 | No | 1-2 times/week | Good | High | No | 2 | 5.9 |
| 2 | 3 | 46 | Female | 159.1 | 69.0 | 27.3 | No | Daily | Excellent | Moderate | No | 3 | 4.8 |
| 3 | 4 | 32 | Male | 170.6 | 76.4 | 26.3 | No | 3-5 times/week | Excellent | Moderate | No | 9 | 6.6 |
| 4 | 5 | 60 | Male | 158.4 | 60.4 | 24.1 | No | 3-5 times/week | Excellent | Low | Yes | 6 | 6.1 |
NOTA: Al inspeccionar las variables 'frecuencia de ejercicio' y 'consumo de alcohol', se identificaron entradas como NaN. Una verificación manual del dataset (ej., en Excel) revela que estos 'NaN' corresponden, de hecho, a la cadena de texto 'None'. Dicha cadena sugiere la ausencia de consumo de alcohol o de ejercicio frecuente. Por lo tanto, se realizará una transformación en estas columnas para eliminar los valores nulos en el nuevo archivo.
df_clean['Exercise_Freq'] = df_clean['Exercise_Freq'].fillna('No Exercise')
df_clean.head(5)
| ID | Age | Gender | Height_cm | Weight_kg | BMI | Smoker | Exercise_Freq | Diet_Quality | Alcohol_Consumption | Chronic_Disease | Stress_Level | Sleep_Hours | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 56 | Other | 177.6 | 37.3 | 11.8 | Yes | No Exercise | Poor | NaN | No | 9 | 8.5 |
| 1 | 2 | 69 | Other | 169.3 | 70.7 | 24.7 | No | 1-2 times/week | Good | High | No | 2 | 5.9 |
| 2 | 3 | 46 | Female | 159.1 | 69.0 | 27.3 | No | Daily | Excellent | Moderate | No | 3 | 4.8 |
| 3 | 4 | 32 | Male | 170.6 | 76.4 | 26.3 | No | 3-5 times/week | Excellent | Moderate | No | 9 | 6.6 |
| 4 | 5 | 60 | Male | 158.4 | 60.4 | 24.1 | No | 3-5 times/week | Excellent | Low | Yes | 6 | 6.1 |
NOTA: Podemos obserar que los datos que antes estaban como tipo 'NaN', ahora se llenaron con 'No Exercise'.
df_clean['Alcohol_Consumption'] = df_clean['Alcohol_Consumption'].fillna('No Alcohol')
df_clean.head(5)
| ID | Age | Gender | Height_cm | Weight_kg | BMI | Smoker | Exercise_Freq | Diet_Quality | Alcohol_Consumption | Chronic_Disease | Stress_Level | Sleep_Hours | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 56 | Other | 177.6 | 37.3 | 11.8 | Yes | No Exercise | Poor | No Alcohol | No | 9 | 8.5 |
| 1 | 2 | 69 | Other | 169.3 | 70.7 | 24.7 | No | 1-2 times/week | Good | High | No | 2 | 5.9 |
| 2 | 3 | 46 | Female | 159.1 | 69.0 | 27.3 | No | Daily | Excellent | Moderate | No | 3 | 4.8 |
| 3 | 4 | 32 | Male | 170.6 | 76.4 | 26.3 | No | 3-5 times/week | Excellent | Moderate | No | 9 | 6.6 |
| 4 | 5 | 60 | Male | 158.4 | 60.4 | 24.1 | No | 3-5 times/week | Excellent | Low | Yes | 6 | 6.1 |
df.isnull().sum()
ID 0 Age 0 Gender 0 Height_cm 0 Weight_kg 0 BMI 0 Smoker 0 Exercise_Freq 1879 Diet_Quality 0 Alcohol_Consumption 1892 Chronic_Disease 0 Stress_Level 0 Sleep_Hours 0 dtype: int64
El dataframe inicial contiene datos nulos, pero no se limpiará directamente. El dataframe que utilizaremos, con valores completos, es el dataframe limpio.
df_clean.isnull().sum()
ID 0 Age 0 Gender 0 Height_cm 0 Weight_kg 0 BMI 0 Smoker 0 Exercise_Freq 0 Diet_Quality 0 Alcohol_Consumption 0 Chronic_Disease 0 Stress_Level 0 Sleep_Hours 0 dtype: int64
Convertir datos de tipo objeto a datos tipo categórico
print('Conversión de tipos de datos.')
categoria_cols = [
'Gender',
'Smoker',
'Exercise_Freq',
'Diet_Quality',
'Alcohol_Consumption',
'Chronic_Disease'
]
for column in categoria_cols:
if column in df_clean.columns:
df_clean[column] = df_clean[column].astype(str).str.strip().str.lower()
df_clean [column] = df_clean[column].astype('category')
print(f"Columna '{column}' convertida a tipo: {df_clean[column].dtype}")
else:
print(f"Columna categórica '{column}' no encontrada.")
Conversión de tipos de datos. Columna 'Gender' convertida a tipo: category Columna 'Smoker' convertida a tipo: category Columna 'Exercise_Freq' convertida a tipo: category Columna 'Diet_Quality' convertida a tipo: category Columna 'Alcohol_Consumption' convertida a tipo: category Columna 'Chronic_Disease' convertida a tipo: category
df_clean.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 7500 entries, 0 to 7499 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID 7500 non-null int64 1 Age 7500 non-null int64 2 Gender 7500 non-null category 3 Height_cm 7500 non-null float64 4 Weight_kg 7500 non-null float64 5 BMI 7500 non-null float64 6 Smoker 7500 non-null category 7 Exercise_Freq 7500 non-null category 8 Diet_Quality 7500 non-null category 9 Alcohol_Consumption 7500 non-null category 10 Chronic_Disease 7500 non-null category 11 Stress_Level 7500 non-null int64 12 Sleep_Hours 7500 non-null float64 dtypes: category(6), float64(4), int64(3) memory usage: 455.2 KB
df_clean.head(5)
| ID | Age | Gender | Height_cm | Weight_kg | BMI | Smoker | Exercise_Freq | Diet_Quality | Alcohol_Consumption | Chronic_Disease | Stress_Level | Sleep_Hours | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 56 | other | 177.6 | 37.3 | 11.8 | yes | no exercise | poor | no alcohol | no | 9 | 8.5 |
| 1 | 2 | 69 | other | 169.3 | 70.7 | 24.7 | no | 1-2 times/week | good | high | no | 2 | 5.9 |
| 2 | 3 | 46 | female | 159.1 | 69.0 | 27.3 | no | daily | excellent | moderate | no | 3 | 4.8 |
| 3 | 4 | 32 | male | 170.6 | 76.4 | 26.3 | no | 3-5 times/week | excellent | moderate | no | 9 | 6.6 |
| 4 | 5 | 60 | male | 158.4 | 60.4 | 24.1 | no | 3-5 times/week | excellent | low | yes | 6 | 6.1 |
Análisis Exploratorio de Datos.📉¶
En esta parte del proyecto, vamos a interactuar directamente con nuestro DataFrame ya limpio para comprender a fondo sus características. Nuestro objetivo principal es identificar patrones ocultos, detectar cualquier anomalía o valor atípico que pueda influir en nuestros análisis, y formular hipótesis iniciales sobre las relaciones entre las variables.
1. ¿Existe una relación significativa entre hábitos como la frecuencia de ejercicio, la calidad de la dieta, el consumo de alcohol y el tabaquismo, y la presencia de enfermedades crónicas, el Índice de Masa Corporal (IMC)?¶
1.1 ¿Influye la calidad de la dieta en el Índice de Masa Corporal (IMC) de los pacientes?🥦¶
order_diet = ['poor', 'average', 'good', 'excellent']
order_init = [i for i in order_diet if i in df_clean['Diet_Quality'].unique()]
grap_diet = px.box(
df_clean,
x = 'Diet_Quality',
y = 'BMI',
title = 'Distribución del IMC por Calidad de la Dieta.',
labels={"Diet_Quality": "Calidad de la Dieta", "BMI": "Índice de Masa Corporal (BMI)"},
category_orders={"Diet_Quality": order_init},
color="Diet_Quality",
color_discrete_sequence=px.colors.sequential.Blugrn
)
grap_diet.update_layout(
xaxis_title="Calidad de la Dieta",
yaxis_title="Índice de Masa Corporal (BMI)",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
)
)
grap_diet.show()
NOTA: No se observa una relación lineal o una tendencia significativa entre la calidad de la dieta y el Índice de Masa Corporal (IMC) en este dataset. Las distribuciones del IMC (incluyendo la mediana, la dispersión y el rango intercuartílico) son notablemente similares entre las categorías de dieta "poor", "average", "good" y "excellent".
1.2 ¿Influye la presencia de enfermedades crónicas Índice de Masa Corporal (IMC) de los pacientes?🦠¶
order_cd = ['no', 'yes']
order_cd = [i for i in order_diet if i in df_clean['Chronic_Disease'].unique()]
grap_cd = px.box(
df_clean,
x = 'Chronic_Disease',
y = 'BMI',
title = 'Distribución del IMC por enfermedad crónica.',
labels={"Chronic_Disease": "Enfermedad Crónica", "BMI": "Índice de Masa Corporal (BMI)"},
category_orders={"Chronic_Disease": order_cd},
color="Chronic_Disease",
color_discrete_sequence=px.colors.sequential.Plasma
)
grap_cd.update_layout(
xaxis_title="Enfermedad Crónica",
yaxis_title="Índice de Masa Corporal (BMI)",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
)
)
grap_cd.show()
NOTA: El análisis de este conjunto de datos revela que el IMC no difiere notablemente entre los individuos con y sin una enfermedad crónica.
1.3 ¿Existe una relación entre los hábitos de tabaquismo y consumo de alcohol y el Índice de Masa Corporal (IMC) de los pacientes?🚬¶
order_ah = ['no', 'yes']
order_ah = [i for i in order_diet if i in df_clean['Smoker'].unique()]
grap_ah = px.box(
df_clean,
x = 'Smoker',
y = 'BMI',
title = 'Distribución del IMC por consumo de tabaco.',
labels={"Smoker": "Fumador", "BMI": "Índice de Masa Corporal (BMI)"},
category_orders={"Smoker": order_ah},
color="Smoker",
color_discrete_sequence=px.colors.sequential.Bluyl
)
grap_ah.update_layout(
xaxis_title="Fumador",
yaxis_title="Índice de Masa Corporal (BMI)",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
)
)
grap_ah.show()
order_ac = ['no alcohol', 'low', 'moderate', 'high']
order_ac = [i for i in order_diet if i in df_clean['Alcohol_Consumption'].unique()]
grap_ac = px.box(
df_clean,
x = 'Alcohol_Consumption',
y = 'BMI',
title = 'Distribución del IMC por consumo de alcohol.',
labels={"Alcohol_Consumption": "Alcohol", "BMI": "Índice de Masa Corporal (BMI)"},
category_orders={"Alcohol_Consumption": order_ac},
color="Alcohol_Consumption",
color_discrete_sequence=px.colors.sequential.Plasma
)
grap_ac.update_layout(
xaxis_title="Consumo Alcohol",
yaxis_title="Índice de Masa Corporal (BMI)",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
)
)
grap_ac.show()
NOTA: Con base en este conjunto de datos, no se observa una correlación evidente entre el alcoholismo, el tabaquismo y el IMC.
2. Influencia de Variables Demográficas: ¿Cómo interactúan la edad y el género con los hábitos de estilo de vida y los resultados de salud observados en el dataset?¶
2.1 ¿Existe alguna relación entre la edad de los pacientes y sus hábitos alimenticios o la frecuencia de ejercicio?⛹🏼♂️¶
df_temp = df_clean.copy()
df_temp['Age'] = pd.to_numeric(df_temp['Age'], errors='coerce')
df_temp.dropna(subset=['Age'], inplace=True)
df_temp['Age'] = df_temp['Age'].astype(int)
bins = [18, 30, 40, 50, 60, 70]
labels = ['18-29 años', '30-39 años', '40-49 años', '50-59 años', '60-69 años']
df_temp['Age_Group'] = pd.cut(df_temp['Age'], bins=bins, labels=labels, right=False, include_lowest=True)
df_temp['Age_Group'] = pd.Categorical(df_temp['Age_Group'], categories=labels, ordered=True)
df_temp.dropna(subset=['Age_Group'], inplace=True)
grap_es = px.histogram(
df_temp,
x='Age_Group',
color='Diet_Quality',
barnorm='percent',
category_orders={"Age_Group": labels},
title='Proporción de Calidad de Dieta por Grupo de Edad',
labels={
"Age_Group": "Grupo de Edad",
"Diet_Quality": "Calidad de Dieta",
"count": "Proporción de Pacientes"
},
color_discrete_sequence=px.colors.sequential.Bluyl
)
grap_es.update_layout(
xaxis_title="Grupo de Edad",
yaxis_title="Proporción de Pacientes",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
),
hovermode="x unified",
legend_title="Calidad de Dieta"
)
grap_es.show()
NOTA: La gráfica sugiere que la edad no es el factor más determinante para la calidad de la dieta. Otros factores (socioeconómicos, educación, cultura, acceso a alimentos saludables, nivel de actividad física, etc.) podrían tener una influencia mucho mayor en los hábitos alimenticios que la edad en sí.
df_temp = df_clean.copy()
df_temp['Age'] = pd.to_numeric(df_temp['Age'], errors='coerce')
df_temp.dropna(subset=['Age'], inplace=True)
df_temp['Age'] = df_temp['Age'].astype(int)
bins = [18, 30, 40, 50, 60, 70]
labels = ['18-29 años', '30-39 años', '40-49 años', '50-59 años', '60-69 años']
df_temp['Age_Group'] = pd.cut(df_temp['Age'], bins=bins, labels=labels, right=False, include_lowest=True)
df_temp['Age_Group'] = pd.Categorical(df_temp['Age_Group'], categories=labels, ordered=True)
df_temp.dropna(subset=['Age_Group'], inplace=True)
grap_ej = px.histogram(
df_temp,
x='Age_Group',
color='Exercise_Freq',
barnorm='percent',
category_orders={"Age_Group": labels},
title='Proporción de Ejercicio de Dieta por Grupo de Edad',
labels={
"Age_Group": "Grupo de Edad",
"Exercise_Freq": "Frecuencia de Ejercicio",
"count": "Proporción de Pacientes"
},
color_discrete_sequence=px.colors.sequential.Blues
)
grap_ej.update_layout(
xaxis_title="Grupo de Edad",
yaxis_title="Proporción de Pacientes",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
),
hovermode="x unified",
legend_title="Frecuencia de Ejercicio"
)
grap_ej.show()
NOTA: En esta gráfica se observa una clara tendencia: las personas de 60 a 69 años muestran una menor frecuencia de actividad física, mientras que el grupo de 30 a 39 años tiende a realizar ejercicio de manera más frecuente.
Se observa que la actividad física tiende a disminuir con la edad, siendo el grupo de 60-69 años el que reporta la mayor proporción de 'no exercise'. En contraste, el grupo de 30-39 años destaca por tener la mayor participación en ejercicio 'daily' y '3-5 times/week', lo que sugiere un pico de actividad física en esta década de vida.
OTRAS PREGUNTAS: En este apartado se pueden analizar diversas preguntas, por ejemplo, la relacion de la actividad fisica con el IMC, el estres, etc.
stress = px.scatter(
df,
x='Sleep_Hours',
y='Stress_Level',
title='Relación entre Horas de Sueño y Nivel de Estrés',
labels={"Sleep_Hours": "Horas de Sueño", "Stress_Level": "Nivel de Estrés"},
hover_data=['Age', 'Gender', 'BMI'],
color_discrete_sequence=['#6a0dad']
)
stress.update_layout(
xaxis_title="Horas Dormidas",
yaxis_title="Nivel de estrés",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
),
hovermode="closest",
legend_title="Frecuencia de Ejercicio"
)
stress.show()
NOTA: Se puede observar que no hay una diferencia drástica en el nivel de estrés entre los individuos que reportan dormir muchas horas y aquellos que duermen pocas horas.
3.2 ¿Existe alguna relación significativa entre las horas de sueño y el Índice de Masa Corporal (IMC)?💤¶
sleep = px.scatter(
df,
x='Sleep_Hours',
y='BMI',
title='Relación entre Horas de Sueño y BMI',
labels={"Sleep_Hours": "Horas de Sueño", "BMI": "Índice de Masa Corporal"},
hover_data=['Age', 'Gender', 'BMI'],
color_discrete_sequence=['#ff7f0e']
)
sleep.update_layout(
xaxis_title="Horas Dormidas",
yaxis_title="IMC",
title_font_size=18,
height=600,
width=1000,
font=dict(
family="Arial, sans-serif",
size=12,
color="Black"
),
hovermode="closest",
legend_title="Sueño y el IBM"
)
sleep.show()
NOTA: Se puede observar que no hay una diferencia drástica en el nivel de IBM entre los individuos que reportan dormir muchas horas y aquellos que duermen pocas horas.
Conclusión Total.📊¶
Las visualizaciones del estilo de vida, salud y datos demográficos en este conjunto de datos revelan patrones variados en las interacciones entre las variables. Se observa que la edad es un factor demográfico clave que influye en los hábitos de frecuencia de ejercicio, mostrando que la actividad física tiende a disminuir en los grupos de mayor edad, mientras que los adultos en sus treinta (30-39 años) exhiben una mayor proporción de ejercicio regular.
En contraste, y de manera consistente a lo largo de diversos análisis, no se identifica una influencia significativa de la calidad de la dieta, el consumo de alcohol, la presencia de enfermedades crónicas, o las horas de sueño sobre el Índice de Masa Corporal (IMC) de los individuos en este dataset. Las distribuciones del IMC para las diferentes categorías de estas variables se mantienen notablemente similares, lo que sugiere que otros factores no explorados en profundidad aquí (como la genética o el metabolismo individual) podrían jugar un papel más dominante en la variación del IMC en esta población.
Finalmente, las relaciones entre el IMC y sus componentes fundamentales se confirman: se observa una fuerte correlación positiva entre el peso corporal y el IMC, y una correlación negativa entre la altura y el IMC, lo cual es consistente con la definición de esta métrica de salud.
Herramientas Utilizadas.⚙️¶
- Jupyter Notebook.🌎
- Python, Pandas, Plotly Express, Matplotlib.🐍